#!/usr/bin/env ruby
# coding: utf-8

#srand(Time.now.to_i)

#実行中のスクリプトのディレクトリをロードパスに追加
#http://vividtone.seesaa.net/article/90206702.html
$:.push(File.expand_path(File.dirname(__FILE__)))

load 'config.rb',true

require 'rubygems'
require 'TwitterClass'
#require 'TwitterClass2'
require 'DatabaseClass'
require 'TalkClass'
#require 'oauth-patch' #Ruby1.9以上の人
#require 'yaml'
require 'json'

class MyBot
	@status='start'

#########
	def order(twitter,order='',user='',m_id='')
		parse = order.split(/[:]/)
		case parse[0]
		when 'follow'
			twitter.follow(user)
		when 'unfollow'
			twitter.unfollow(user)
		when 'retweet'
			twitter.retweet(m_id)
		when 'favorite'
			twitter.favorite(m_id)
		when 'continue'
			@status = 'continue'
		end
	end
#########

	def initialize
		@status = 'initialize'
		@logdata = DatabaseClass.new
		@twitter = TwitterClass.new($config[:CONSUMER_KEY],$config[:CONSUMER_SECRET],$config[:ACCESS_TOKEN],$config[:ACCESS_TOKEN_SECRET],$config[:TWITPIC_API_KEY])

		my={'name'=>$config[:MY_NAME],'call'=>$config[:MY_CALL],'admin'=>$config[:ADMIN_NAME]}

		options={'bitly_id'=>$config[:BITLY_ID],'bitly_key'=>$config[:BITLY_API_KEY]}

		init_files={'trans_data_file'=>$config[:TRANS_DATA_FILE],
			'reply_data_file'=>$config[:REPLY_DATA_FILE],
			'personal_data_file'=>$config[:PERSONAL_DATA_FILE],
			'speak_data_file'=>$config[:SPEAK_DATA_FILE],
			'dict_data_file'=>$config[:DICT_DATA_FILE]}

		@talk = TalkClass.new(my,options,init_files,'test.db')
		@data = @logdata.get_dataset
	end

	def post_error?
		@status = 'Check post error'
		#POST規制解除チェケ
		now_error_count = @data['post_error'].to_i
		if (@data['status'] == "post_error")
			if (twitter.connect?) then
				puts "+++status change to normal"
				@twitter.update("#{data['error_start']} からポスト規制されてました。 \##{$config[:MY_NAME]}_info")
				@logdata.update_dataset("status","normal")
				@logdata.update_dataset("error_start","0")
				@logdata.update_dataset("post_error","0")
				now_error_count = 0
				return false
			else
				now_error_count += 1
				if (now_error_count > 3) then
					@logdata.update_dataset("status","post_error")
					@logdata.update_dataset("error_start",Time.now.strftime("%Y/%m/%d %H:%M:%S"))
					@logdata.update_dataset("post_error","#{now_error_count}")
					puts "[#{Time.now.strftime("%Y/%m/%d %H:%M:%S")}] POST ERROR count #{now_error_count}"
					#exit
					return true
				end
			end
		end
		return false
	end

	def read_timeline
		@status = 'reading time line'

		get_statuses = Array.new
		#ツィートに関する処理
		puts "---- get timeline ----"
		since=@data['latestTW']
		##ツィートを取得
		if(since!='0') then
			statuses = @twitter.get_timeline("since_id=#{since}")
		else 
			statuses = @twitter.get_timeline()
		end

		##対応を考える
		latestTW=''
		begin
			if (statuses!=nil) then
				JSON.parse(statuses.body).each do |status| #reverse_eachが使えないとき
					next if(status==nil)
					get_statuses.push(status)
					latestTW=status['id'] if(latestTW=='') #eachなので一番最初のが最新のtweet
					@logdata.recvTW(status['id'],status['created_at'],status['user']['screen_name'],status['text'])
					@talk.parse('TW',status['user']['screen_name'],status['text'],status['id'])
				end
			end
		rescue JSON::ParserError
			time = Time.now.strftime("%Y/%m/%d %H:%M:%S")
			puts "#{time}\t[Error:TL] cannot parse json"
		end
		@logdata.latest_TW(latestTW)  if(latestTW!=nil and latestTW!='')
		puts "---- All #{get_statuses.size} stasuses  ----\n\n"

		return get_statuses
	end

	def read_directmessage
		@status = 'reading direct messages'

		get_messages = Array.new
		#ダイレクトメッセージに関する処理
		puts "---- get direct messages ----"
		since=@data['latestDM']
		##ダイレクトメッセージを取得
		if(since!='0') then
			messages = @twitter.get_directmessage("since_id=#{since}")
		else 
			messages = @twitter.get_directmessage()
		end

		##対応を考える
		latestDM=''
		begin
			if (messages!=nil) then
				JSON.parse(messages.body).each do |message|
					next if(message==nil)
					get_messages.push(message)
					@latestDM=message['id'] if(latestDM=='') #eachなので一番最初のが最新のtweet
					@logdata.recvDM(message['id'],message['created_at'],message['sender']['screen_name'],message['text'])
					@talk.parse('DM',message['sender']['screen_name'],message['text'],message['id'])
				end
			end
		rescue JSON::ParserError
			time = Time.now.strftime("%Y/%m/%d %H:%M:%S")
			puts "#{time}\t[Error:DM] cannot parse json"
		end
		@logdata.latest_DM(latestDM) if(latestDM!=nil  and latestDM!='')
		puts "---- All #{get_messages.size} messages  ----\n\n"

		return get_messages
	end

	#独り言を追加する
	def add_speak
		#自分から話しかける
		@talk.parse
	end

	#返事を初期化する
	def reflesh
		@status = 'Reflesh'
		@talk.reflesh
	end

	def sending
		@status = 'Sending messages'
		sended_message = Array.new


		#連続エラー数を数える
		error_count = 0

		puts "---- update messages -----"
		responses = @talk.responses

		responses.each do |response|
			next if(response==nil)
			success=false
			response['messages'].each do |message|

				case response['mode']
				when 'say','reply'
					tweet = message
					tweet = "@#{response['to']} #{tweet}" if response['mode'] == 'reply'
					success = @twitter.update(tweet)
				when 'send'
					tweet = "D #{response['to']} #{message}"
					success = @twitter.send_direct(tweet)
				end

				#ログを保存
				if(success) then
					puts "[#{message}]-- success"
					error_count = 0
					case
					when 'say','reply'
						@logdata.sendTW(response['to'],tweet)
					when 'send'
						@logdata.sendDM(response['to'],tweet)
					end
				else
					puts "[#{message}]-- failed"
					error_count += 1
				end
				sended_message.push({'message'=>tweet,'success'=>success})
			end
		end
		return {'error'=>error_count,'messages'=>sended_message}
	end

	def end_bot(error_count)
		#POSTエラー記録
		if (error_count > 3) then
			@logdata.update_dataset("status","post_error")
			@logdata.update_dataset("error_start",Time.now.strftime("%Y/%m/%d %H:%M:%S"))
			puts "status : POST ERROR"
		end
		@logdata.update_dataset("post_error","#{error_count}")
		@status = 'end'
	end

	def close
		@logdata.close
		@talk.close
	end
end

puts "[#{Time.now.strftime("%Y/%m/%d %H:%M:%S")}] ==== Start Bot  ===="
librobot = MyBot.new
if !librobot.post_error? then
	puts "=== read TL ==="
	librobot.read_timeline
	puts "=== read DM ==="
	librobot.read_directmessage

	librobot.add_speak
	puts "=== send message ==="
	result = librobot.sending
	librobot.end_bot(result['error'])
end
librobot.close
puts "[#{Time.now.strftime("%Y/%m/%d %H:%M:%S")}] ==== End Bot  ===="

